/* eslint-disable multiline-ternary */
/* eslint-disable implicit-arrow-linebreak */
import { useSkin } from '@hooks/useSkin'
import { Icon } from '@iconify/react'
import classNames from 'classnames'
import { useFormik } from 'formik'
import React, { memo, useState } from 'react'
import {
  useStripe,
  CardCvcElement,
  CardExpiryElement,
  CardNumberElement,
  useElements
} from '@stripe/react-stripe-js'
import { Check, X } from 'react-feather'
import InputMask from 'react-input-mask'
import { useDispatch, useSelector } from 'react-redux'
import {
  Badge,
  Button,
  Col,
  Form,
  Modal,
  ModalBody,
  ModalHeader,
  Row,
  Spinner
} from 'reactstrap'
import * as Yup from 'yup'
import amex from '../../assets/images/amex.png'
import {
  deleteStripeCardAction,
  registerMoreStripeCardAction,
  updateStripeCardAction
} from '../../redux/stripe/stripeAction'
import { isObjEmpty } from '../../utility/Utils'
import useScrollBar from '../../utility/hooks/useScrollBar'
import FormGroupElement from '../formGroup/FormGroupElement'
import DeleteModal from './DeleteModal'

const PaymentModalBox = ({ basicModal, setBasicModal }) => {
  useScrollBar({ open: basicModal })
  const { skin } = useSkin()
  const dispatch = useDispatch()
  const [focusElement, setFocusElement] = useState('')
  const [showForm, setShowForm] = useState(false)
  const [deleteModal, setDeleteModal] = useState(false)
  const [selectedAutoPayCardId, setSelectedAutoPayCardId] = useState(null)
  const [deleteId, setDeleteId] = useState('')
  const element = useElements()
  const [card, setCard] = useState({
    number: {
      brand: '',
      error: null,
      empty: true
    },
    cvc: {
      error: null,
      empty: true
    },
    expiry: {
      error: null,
      empty: true
    }
  })
  const stripe = useStripe() // Access the Stripe object
  const [error, setError] = useState(null)
  const updateCard = (key, data) => {
    setCard((prev) => ({ ...prev, [key]: data }))
  }
  const options = {
    style: {
      base: {
        // color: theme.palette.text.primary
      },
      invalid: {
        color: 'unset'
      }
    }
  }
  const {
    getAllCards,
    getAllCardsLoading,
    registerCardsLoading,
    deleteStripeCardLoading,
    updateStripeCardLoading,
    registerMoreStripeCardLoading
  } = useSelector((state) => state.stripe)
  const rows = getAllCards?.sources
  const StripePaymentSchema = Yup.object().shape({
    card_number: Yup.string().required('Card number is a required field'),
    card_expiry: Yup.string().required('Expiry date is a required field'),
    card_cvc: Yup.string().required('CVC number is a required field'),
    // zip_code: Yup.number().required(),
    autoPay: Yup.boolean(),
    default_payment: Yup.boolean()
  })
  const formik = useFormik({
    initialValues: {
      card_number: '',
      card_expiry: '',
      card_cvc: '',
      // zip_code: '',
      autoPay: false,
      default_payment: false,
      default_card: rows?.filter(
        (item) =>
          item?.id === getAllCards?.invoice_settings?.default_payment_method
      )[0]?.id,
      auto_pay_card_id:
        rows?.filter((item) => item?.id === getAllCards?.auto_pay_card_id)[0]
          ?.id || ''
    },
    enableReinitialize: true,
    // validationSchema: StripePaymentSchema,
    onSubmit: async (values, { resetForm }) => {
      try {
        const cardNumber = element.getElement(CardNumberElement) // Assuming 'element' is defined
        const { paymentMethod, error } = await stripe.createPaymentMethod({
          type: 'card',
          card: cardNumber
        })
        if (error) {
          if (error.type === 'validation_error') {
            setError(error.message)
            console.error('Validation error:', error)
            return
          }
          if (error.type === 'card_error') {
            setError(error.message)
            console.error('Card error:', error)
            return
          }
        }

        if (!error) {
          // Dispatch only if there's no error
          
          const data = {
            payment_method_id: paymentMethod.id,
            default_payment: values.default_payment,
            auto_pay: values.autoPay,
            auto_pay_card_id: ''
          }
          dispatch(
            registerMoreStripeCardAction({
              data,
              callback: () => {
                resetForm()
                setShowForm(false)
                setBasicModal(false)
              }
            })
          )
        }
      } catch (error) {
        console.error('An unexpected error occurred:', error)
      } finally {
      }
    }
  })

  const handleUpdateCard = () => {
    
    const data = {
      default_source: formik.values.default_card,
      auto_pay: !!formik.values.auto_pay_card_id,
      auto_pay_card_id: formik.values.auto_pay_card_id
    }
    dispatch(updateStripeCardAction({ data }))
  }
  const handleDeleteCard = () => {
    dispatch(
      deleteStripeCardAction({
        id: deleteId,
        callback: () => {
          setDeleteModal(false)
          // setBasicModal(true)
        }
      })
    )
  }
  const handleShowForm = () => {
    setShowForm(!showForm)
  }
  const handleDelete = (id) => {
    setDeleteId(id)
    setBasicModal(true)
    setDeleteModal(!deleteModal)
  }

  //** Using Regex  */
  const handleCardNumberChange = (event) => {
    const input = event.target.value.replace(/\D/g, '')
    const formattedInput = input.replace(/(\d{4})(?=\d)/g, '$1 ')
    formik.setFieldValue('card_number', formattedInput)
  }
  const handleCvcInput = (event) => {
    const value = event.target.value
    if (value.length >= 3) {
      event.target.value = value.slice(0, 4)
      formik.setFieldValue('card_cvc', value)
    }
  }
  const handleExpiryDate = (event) => {
    const { value } = event.target
    const month = parseInt(value, 10)

    if (month < 1 || month > 12) {
      event.target.value = ''
    }
    formik.setFieldValue('card_expiry', event.target.value)
  }
  const cancel = (
    <X
      className="pointer"
      onClick={() => {
        setBasicModal(false)
        formik.resetForm()
        setShowForm(false)
      }}
    />
  )

  const handleAutoPayCheckboxChange = (cardId) => {
    if (selectedAutoPayCardId === cardId) {
      formik.setFieldValue('auto_pay_card_id', null)
      formik.setFieldValue('autoPay', false)
      setSelectedAutoPayCardId(null)
    } else {
      formik.setFieldValue('autoPay', true)
      formik.setFieldValue('auto_pay_card_id', cardId)
      setSelectedAutoPayCardId(cardId)
    }
  }
  return (
    <div>
      <Modal
        isOpen={basicModal}
        toggle={() => {
          setBasicModal(!basicModal)
          formik.resetForm()
          setShowForm(false)
        }}
        className="ModalDialoge payment-modal"
      >
        {/* <PaymentElement/> */}
        <ModalHeader className="mt-1 ModalHeader pb-0 d-flex align-items-center">
          <span className="mb-0 fw-bold fs-22 black">Payment Method</span>
          {cancel}
        </ModalHeader>
        <ModalBody className="modalBody">
          <Row>
            <Col lg={12}>
              <Form onSubmit={formik.handleSubmit}>
                {showForm !== true ? (
                  <Col lg={6}>
                    <Button
                      className="secondary-btn mb-2 w-100 add-card"
                      size="sm"
                      onClick={handleShowForm}
                    >
                      Add More Payment
                    </Button>
                  </Col>
                ) : null}
                {showForm && (
                  <Row>
                    <Col lg={12}>
                      <label htmlFor="expiry" className="pl-10px form-label">
                        Card Number
                      </label>
                      <div className="card-element-container">
                        <CardNumberElement
                          options={{
                            ...options,
                            placeholder: 'XXXX XXXX XXXX XXXX'
                          }}
                          onChange={(e) => {
                            const { brand, error, empty } = e
                            updateCard('number', {
                              brand,
                              error,
                              empty
                            })
                          }}
                          onFocus={(e) => {
                            setFocusElement(e.elementType)
                          }}
                        />
                      </div>
                      <p className="error-class">
                        {' '}
                        {card.number.error?.message || ''}
                      </p>

                      {/* <FormGroupElement
                        inputType="text"
                        label="Card Number"
                        value={formik.values.card_number}
                        onChange={handleCardNumberChange}
                        inputName="card_number"
                        // pattern="\d{4}\s\d{4}\s\d{4}\s\d{4}"
                        maxLength={19}
                        placeholder="1234 XXXX XXXX 1234"
                        inputClassName={classNames({
                          'radius-25 border px-1 w-100': true,
                          invalid: !!formik.errors.card_number
                        })}
                      /> */}
                    </Col>
                    <Col lg={8}>
                      <div className="mb-1">
                        <label htmlFor="expiry" className="px-1 form-label">
                          Expiration Date
                        </label>
                        <div className="card-element-container">
                          <CardExpiryElement
                            options={options}
                            onChange={(e) => {
                              const { empty, error } = e
                              updateCard('expiry', { empty, error })
                            }}
                            onFocus={(e) => {
                              setFocusElement(e.elementType)
                            }}
                          />
                        </div>
                        <p className="error-class">
                          {card.expiry.error?.message || ''}
                        </p>
                        {/* <InputMask
                          id="expiry"
                          mask="99/99"
                          maskPlaceholder="MM/YY"
                          className={classNames({
                            'radius-25 border px-1 form-control w-100': true,
                            invalid: !!formik.errors.card_expiry
                          })}
                          onChange={(e) => handleExpiryDate(e)}
                          alwaysShowMask={true}
                        /> */}
                      </div>
                    </Col>

                    <Col lg={4}>
                      <div>
                        <label htmlFor="expiry" className="pl-10px form-label">
                          Card Number
                        </label>
                        <div className="card-element-container">
                          <CardCvcElement
                            options={options}
                            onChange={(e) => {
                              const { error, empty } = e
                              updateCard('cvc', { empty, error })
                            }}
                            onFocus={(e) => {
                              setFocusElement(e.elementType)
                            }}
                          />
                        </div>
                        <p className="error-class">
                          {card.cvc.error?.message || ''}
                        </p>
                        {/* <FormGroupElement
                          inputType="text"
                          label="CVC"
                          labelClassName="sm-label-margin-top"
                          // value={formik.values.card_cvc}
                          onChange={(e) => handleCvcInput(e)}
                          inputName="card_cvc"
                          placeholder="123"
                          inputClassName={classNames({
                            'radius-25 border px-1 w-100': true,
                            invalid: !!formik.errors.card_cvc
                          })}
                        /> */}
                      </div>
                    </Col>
                    <Col lg={12}>
                      <div className="d-flex mt-1 align-items-center payment-checkbox ">
                        {/* <FormGroupElement
                          type="number"
                          label="Zip Code"
                          labelClassName="fs-11 pdl-1 "
                          inputName="zip_code"
                          inputClassName={classNames({
                            'form-fields  border radius-25': true,
                            lightColors: skin === 'dark',
                            invalid:
                              formik.errors.zip_code && formik.touched.zip_code
                          })}
                          {...formik.getFieldProps('zip_code')}
                          // formikTouched={formik.touched.zip_code}
                          // formikError={formik.errors.zip_code}
                        /> */}
                        <FormGroupElement
                          type="checkbox"
                          label="Default payment method"
                          labelClassName="fs-11 pdl-1"
                          inputName="default_payment "
                          formGroupClassName="client_profile--checkbox pdl-1 mrgin-top ml-1"
                          inputClassName={classNames({
                            lightColors: skin === 'dark pdl-1'
                          })}
                          // checked={formik.values.default_payment === true}
                          // value={formik.values.default_payment}
                          onChange={(e) => {
                            formik.setFieldValue(
                              `default_payment`,
                              e.target.checked
                            )
                          }}
                        />
                        <FormGroupElement
                          type="checkbox"
                          //checked={formik.values.autoPay}
                          label="Auto Pay"
                          labelClassName="fs-11"
                          inputName="autoPay"
                          onChange={(e) =>
                            formik.setFieldValue('autoPay', e.target.checked)
                          }
                          inputClassName={classNames({
                            lightColors: skin === 'dark'
                          })}
                          formGroupClassName="client_profile--checkbox"
                        />
                      </div>
                    </Col>
                    <Col lg={12}>
                      <div className="ModalFooter float-right mb-1 payment-box-footer ">
                        <Button
                          size="sm"
                          type="button"
                          className="ModalCancel"
                          onClick={() => {
                            formik.handleReset()
                            setShowForm(!showForm)
                          }}
                        >
                          Cancel
                        </Button>
                        <Button
                          size="sm"
                          type="submit"
                          className="ModalAdd ml-1  "
                          disabled={
                            registerCardsLoading ||
                            registerMoreStripeCardLoading
                          }
                        >
                          {registerCardsLoading ||
                          registerMoreStripeCardLoading ? (
                            <Spinner
                              size="sm"
                              className="add-card-spinner-size"
                            />
                          ) : (
                            <Check size={13} />
                          )}
                          <span className="px-1">Add</span>
                        </Button>
                      </div>
                    </Col>
                  </Row>
                )}
                <Row>
                  <hr />

                  <Col>
                    <h5 className="black">Your Cards</h5>
                    {getAllCardsLoading ? (
                      <div className="d-flex justify-content-center">
                        <Spinner size="lg" color="blue" />
                      </div>
                    ) : rows?.length > 0 ? (
                      rows?.map((item, i) => {
                        const cardFormat =
                          item?.card?.brand === 'amex'
                            ? `XXXX XXXXXX X${item?.card?.last4}`
                            : `XXXX XXXX XXXX ${item?.card?.last4}`
                        return (
                          <div className="mb-2" key={i}>
                            <div className="d-flex align-items-center justify-content-between">
                              <div
                                className="saved_card_elements border"
                                onClick={() =>
                                  formik.setFieldValue('default_card', item.id)
                                }
                              >
                                <div className="saved_card_elements--card">
                                  {item?.card?.brand === 'visa' ? (
                                    <Icon icon="logos:visa" width={35} />
                                  ) : item?.card?.brand === 'mastercard' ? (
                                    <Icon icon="logos:mastercard" width={33} />
                                  ) : item?.card?.brand === 'amex' ? (
                                    <img
                                      src={amex}
                                      alt={item?.card?.brand}
                                      width={33}
                                    />
                                  ) : (
                                    <Icon
                                      icon="fluent:payment-20-filled"
                                      width={33}
                                    />
                                  )}

                                  <FormGroupElement
                                    type="text"
                                    inputName="cardNumber"
                                    value={cardFormat}
                                    disabled
                                    inputClassName={classNames({
                                      lightColors: skin === 'dark',
                                      'saved_card_elements--cardNumber--input form-setting': true
                                    })}
                                    formGroupClassName="saved_card_elements--cardNumber"
                                  />
                                </div>
                                <div className="saved_card_elements--sm-default-box lg-none-preview">
                                  {formik.values.default_card === item.id && (
                                    <Badge className="saved_card_elements--default-badge">
                                      Default Card
                                    </Badge>
                                  )}
                                </div>

                                <div className="saved_card_elements--cardExpiry">
                                  <FormGroupElement
                                    type="text"
                                    inputName="cardexpiry"
                                    value={`${item?.card?.exp_month}/${
                                      item?.card?.exp_year % 100
                                    }`}
                                    disabled
                                    inputClassName={classNames({
                                      lightColors: skin === 'dark',
                                      'saved_card_elements--cardNumber--input ': true
                                    })}
                                    formGroupClassName="saved_card_elements--cardNumber"
                                  />
                                </div>
                              </div>
                              <div
                                className="payment-trash-btn"
                                onClick={() => handleDelete(item?.id)}
                              >
                                <Icon
                                  icon="subway:delete"
                                  color="#555"
                                  width="12"
                                  height="12"
                                />
                              </div>
                            </div>
                            <div className="radio-setting pdl-1 ">
                              <FormGroupElement
                                type="radio"
                                inputName={item.id}
                                // value={formik.values.default_card}
                                // defaultValue={formik.values.default_card}
                                label="Default payment method"
                                labelClassName="fs-s-med "
                                checked={formik.values.default_card === item.id}
                                onChange={() =>
                                  formik.setFieldValue('default_card', item.id)
                                }
                                inputClassName={classNames({
                                  lightColors: skin === 'dark'
                                })}
                                formGroupClassName="client_profile--checkbox saved_card_elements--radio"
                              />
                              <FormGroupElement
                                type="checkbox"
                                label="AutoPay"
                                labelClassName="fs-s-med pdl-1"
                                inputName={`AutoPay-${item.id}`}
                                checked={
                                  formik.values.auto_pay_card_id === item.id
                                }
                                onChange={() =>
                                  handleAutoPayCheckboxChange(item.id)
                                }
                                inputClassName={classNames({
                                  lightColors: skin === 'dark'
                                })}
                                formGroupClassName="client_profile--checkbox saved_card_elements--radio"
                              />
                            </div>
                          </div>
                        )
                      })
                    ) : (
                      <div className="text-center py-1">No Cards</div>
                    )}

                    <div className="float-right my-1 payment-detail-btn">
                      <Button
                        size="sm"
                        type="button"
                        className="ModalCancel "
                        onClick={() => {
                          setBasicModal(!basicModal)
                          formik.resetForm()
                          setShowForm(false)
                        }}
                      >
                        Cancel
                      </Button>
                      <Button
                        type="button"
                        disabled={updateStripeCardLoading || !rows?.length}
                        size="sm"
                        className="reqbgColor  px-2 ml-1"
                        onClick={handleUpdateCard}
                      >
                        {updateStripeCardLoading ? (
                          <Spinner size="sm" className="spinner-size-update" />
                        ) : (
                          <Check size={12.5} />
                        )}
                        <span className="px-1">Save</span>
                      </Button>
                    </div>
                  </Col>
                </Row>
              </Form>
            </Col>
          </Row>
        </ModalBody>
      </Modal>
      <DeleteModal
        deleteModal={deleteModal}
        setDeleteModal={setDeleteModal}
        loading={deleteStripeCardLoading}
        submit={handleDeleteCard}
        setBasicModal={setBasicModal}
      />
    </div>
  )
}
const compare = (prevProps, nextProps) =>
  JSON.stringify(prevProps) === JSON.stringify(nextProps)

export default memo(PaymentModalBox, compare)
